package com.ikun.common.config.rabbitMQ;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ配置
 *
 * @author Guio
 */
@Slf4j
@Configuration
public class RabbitMQConfig {

    //保存队列
    public static final String COURSE_SAVE_QUEUE = "edu-course-save-queue";
    //删除队列
    public static final String COURSE_REMOVE_QUEUE = "edu-course-remove-queue";

    //课程交换机
    public static final String COURSE_EXCHANGE = "edu-course-exchange";

    //保存绑定键
    public static final String COURSE_SAVE_KEY = "edu-course-save";
    //删除绑定键
    public static final String COURSE_REMOVE_KEY = "edu-course-remove";

    /**
     * 返回课程保存队列
     */
    @Bean
    public Queue courseSaveQueue() {
        return new Queue(COURSE_SAVE_QUEUE);
    }

    /**
     * 返回删除课程队列
     */
    @Bean
    public Queue courseRemoveQueue() {
        return new Queue(COURSE_REMOVE_QUEUE);
    }

    /**
     * 返回课程交换机
     */
    @Bean
    public Exchange courseExchange() {
        return new TopicExchange(COURSE_EXCHANGE);
    }

    /**
     * 绑定保存队列和交换机
     */
    @Bean
    public Binding bindCourseSave() {
        return BindingBuilder.bind(courseSaveQueue()).to(courseExchange()).with(COURSE_SAVE_KEY).noargs();
    }

    /**
     * 绑定删除队列和交换机
     */
    @Bean
    public Binding bindCourseRemove() {
        return BindingBuilder.bind(courseRemoveQueue()).to(courseExchange()).with(COURSE_REMOVE_KEY).noargs();
    }

    /**
     * 配置自定义的Rabbit模版对象
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //设置设发布确认的回调方法
        //参数： 1：消息内容（包含id） 2：是否确认 3：原因
        rabbitTemplate.setConfirmCallback((correlationData, b, s) -> {
            if (b) {
                log.info("Rabbit发送成功");
            } else {
                log.info("发送失败：{}，是否确认：{}，失败原因：{}",
                        correlationData, false, s);
            }
        });
        //设置返回机制的回调
        //参数 1.消息内容 2.响应代码 3.响应文本 4.交换机 5.路由键
        rabbitTemplate.setReturnCallback((message, i, s, s1, key)
                -> log.error("消息返回：{}，响应代码：{}，响应文本：{}，交换机：{}，路由键：{}",
                message, i, s, s1, key));
        return rabbitTemplate;
    }

}
